﻿using System;
using System.IO.IsolatedStorage;
using System.IO;
using System.Diagnostics;
using System.Xml.Serialization;

namespace FbHelperWP7NonUi.Settings
{
    public sealed class ProgramState
    {
        private static Boolean isTestRun = false;

        private const String s_fileName = "ProgramState.xml";

        private static readonly Object s_syncRoot = new Object();

        private static ProgramState s_programState = null;

        public ProgramState()
        {
            if (s_programState != null)
                throw new InvalidOperationException( "Instance of this class was already created" );

            TextStyle = new TextStyleSettings();
            History = new FilesHistory();
        }

        public TextStyleSettings TextStyle
        {
            get;
            set;
        }

        public FilesHistory History
        {
            get;
            set;
        }

        public void Save()
        {
            if (isTestRun)
                return;

            using (var storage = CreateIsolatedStorageFile())
            {
                if (storage.FileExists( s_fileName ))
                    storage.DeleteFile( s_fileName );

                using (var file = storage.OpenFile( s_fileName, FileMode.Create, FileAccess.Write ))
                {
                    var serialisation = Serialize();

                    file.Write( serialisation, 0, serialisation.Length );
                }
            }
        }

        public static ProgramState CurrentState
        {
            get
            {
                if (s_programState == null)
                {
                    lock (s_syncRoot)
                    {
                        if (s_programState == null)
                            s_programState = LoadProgramState();
                    }
                }

                return s_programState;
            }
        }

        private static IsolatedStorageFile CreateIsolatedStorageFile()
        {
#if WINDOWS_PHONE
                return IsolatedStorageFile.GetUserStoreForApplication();
#else
            return IsolatedStorageFile.GetUserStoreForDomain();
#endif
        }

        private static ProgramState LoadProgramState()
        {
            try
            {
                using (IsolatedStorageFile storage = CreateIsolatedStorageFile())
                {
                    if (!storage.FileExists( s_fileName ))
                        return new ProgramState();

                    var file = storage.OpenFile( s_fileName, FileMode.Open, FileAccess.Read );

                    using (var reader = new BinaryReader( file ))
                    {
                        var bytes = reader.ReadBytes( 1024 * 1024 * 16 );//Это нехорошо, но: читаем 16 МБайт от файла.

                        return Deserialize( bytes );
                    }

                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine( ex );
            }

            return new ProgramState();
        }

        private static ProgramState Deserialize( Byte[] bytes )
        {
            var serializer = new XmlSerializer( typeof( ProgramState ) );

            using (var stream = new MemoryStream( bytes ))
            {
                stream.Seek( 0, SeekOrigin.Begin );

                var result = serializer.Deserialize( stream ) as ProgramState;

                if (result == null)
                    return new ProgramState();

                return result;
            }
        }

        private Byte[] Serialize()
        {
            var serializer = new XmlSerializer( typeof( ProgramState ) );

            using (var stream = new MemoryStream())
            {
                serializer.Serialize( stream, this );

                return stream.ToArray();
            }
        }
    }
}
